package org.al.poc.router;

import java.io.IOException;
import java.net.ServerSocket;

import org.al.poc.persistence.beans.Connection;
import org.al.poc.persistence.beans.Order;
import org.al.poc.sockets.AbstractServerThread;
import org.al.poc.sockets.NoMoreServerException;
import org.al.poc.sockets.SocketManager;

public class ServerPartThread extends AbstractServerThread {

	
	
	public ServerPartThread(ServerSocket ss) {
		super(ss);
	}
	

	
	@Override
	protected void processConnection(Connection connection) throws Exception {
		
//		WebServerInfo info = RoundRobin.getNextServer();
//
//		ClientPart client = null;
//		try {
//			client = new ClientPart(info);
//		
//		} 
//		catch (Exception e) {
//			
//			// SERVER DOWN
//			RoundRobin.removeServer(info.getServerIndex());
//			
//			try {
//				info = RoundRobin.getNextServer();
//				client = new ClientPart(info);
//				
//			} catch (Exception e1) {
//				e1.printStackTrace();
//			}
//		}
//		
//		// Il reste un serveur dispo
//		if (client != null) {
//			
//			Connection response = client.transmitConnection(connection);
//			
//			if (response != null) {
//				// Associate the sessionID to the server
//				RoundRobin.setConnection(response.getSessionId(), info);
//				
//				// Send the response to the client
//				SocketManager manager = new SocketManager(socket);
//				manager.writeObject(response);
//			}
//		}
//		
		
//		try { algoConnection(connection); }
//		catch(Exception e) {
//			e.printStackTrace();
//			try { algoConnection(connection); }
//			catch(Exception e1) { 
//				e.printStackTrace();
//				System.err.println("aucun serveur dispo (connection)"); }
//		}
		
		
		// 1st try
		if (! algoConnection(connection)) {
			
			// 2nd try
			algoConnection(connection);
		}

		
		
//		if (! socket.isClosed()) 
//			try { socket.close(); }
//			catch(Exception e) { System.err.println("can't close socket"); }
	}

	
	
	
	@Override
	protected void processOrder(Order order) throws Exception {
//		WebServerInfo server = RoundRobin.getAssociatedServer(order.getSessionId());
//
//		if (server != null) {
//			
//			ClientPart client = null;
//			try {
//				client = new ClientPart(server);
//			
//			} 
//			catch (Exception e) {
//				
//				// SERVER DOWN
//				RoundRobin.removeServer(server.getServerIndex());
//				
//				try {
//					server = RoundRobin.getNextServer();
//					client = new ClientPart(server);
//					
//				} catch (Exception e1) {
//					e1.printStackTrace();
//				}
//			}
//			
//			if (client != null) {
//				Order response = client.transmitOrder(order);
//				
//				if (response != null) {
//					
//					// Send the response to the client
//					SocketManager manager = new SocketManager(socket);
//					manager.writeObject(response);
//				}
//			}
//			
//		}
	
		// 1st try
		if (! algoOrder(order)) {
			
			// 2nd try
			if (! algoOrder(order))
				throw new NoMoreServerException();
		}
		
//		try { 
//			algoOrder(order); 
//		}
//		catch(Exception e) {
//			
//			System.out.println("1st try");
//			e.printStackTrace();
//			
//			try { 
//				algoOrder(order); 
//			}
//			catch(Exception e1) {
//				
//				System.out.println("2nd try");
//				e.printStackTrace();
//				System.err.println("aucun serveur dispo (order)"); }
//		}

//		if (! socket.isClosed()) 
//			try { socket.close(); }
//			catch(Exception e) { System.err.println("can't close socket"); }
	}
	
	
	private boolean algoConnection(Connection connection) {
		
		WebServerInfo server = RoundRobin.getNextServer();
		if (server == null) return false;
		
		try {
			ClientPart client = new ClientPart(server);
			
			Connection response = client.transmitConnection(connection);
			if (response == null) return false;
		
			// Associate the sessionID to the server
			RoundRobin.setConnection(response.getSessionId(), server);
		
			SocketManager manager = new SocketManager(socket);
			manager.writeObject((Connection) response);
			
			return true;
		}
		catch(IOException e) {
			
			RoundRobin.removeServer(server.getServerIndex());
//			System.out.println(server.getServerIndex() + "OUT !");
			return false;
		}
	}
	
	
	
	private boolean algoOrder(Order order) {
		WebServerInfo server = RoundRobin.getAssociatedServer(order.getSessionId());
		if (server == null) return false;
		
		try {
			ClientPart client = new ClientPart(server);

			Order response = client.transmitOrder(order);
	
			SocketManager manager = new SocketManager(socket);
			manager.writeObject((Order) response);
			
			return true;
		}
		catch(IOException e) {
			
			RoundRobin.removeServer(server.getServerIndex());
//			System.out.println(server.getServerIndex() + "OUT !");
			return false;
		}
	}
	
}
